package com.zz.zjc.service;

import com.alibaba.fastjson.JSONObject;
import com.zz.zjc.model.Player;
import com.zz.zjc.model.User;
import com.zz.zjc.util.SpringContextUtil;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/webSocketDzpk/{sid}")
@Component
public class WebSocketDzpkServer {


    static UserService userService = null;


    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    //concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String, Player> playPools = new ConcurrentHashMap<>();
    private static ConcurrentHashMap<Integer, Player> playMap = new ConcurrentHashMap<>();

    {
        playMap.put(1, new Player(0));
        playMap.put(2, new Player(0));
        playMap.put(3, new Player(0));
        playMap.put(4, new Player(0));
    }

    //发送消息
    public void sendMessage(Session session, String message) {
        if (session != null) {
            synchronized (session) {
                System.out.println("发送数据：" + message);
                try {
                    session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public void loginOut(String id) {
        Session session = sessionPools.get(id);
        if (session != null) {
            try {
                sendMessage(session, getJsonStr("error", "xitong", "账号在其他地方登录"));
                session.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void sendInfoAll(String message) {
        for (Session session : sessionPools.values()) {
            try {
                sendMessage(session, message);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "sid") String sid) {
        //先判断 用户真实  过滤假用户
        if (userService == null) {
            userService = (UserService) SpringContextUtil.getBean("userService");
        }
        if (onlineNum.get() >= 4) {
            sendMessage(session, getJsonStr("error", "xitong", "当前人数过多，请稍后再试"));
        }
        User user = userService.get(Integer.parseInt(sid));
        if (user != null) {
            loginOut(sid);
            sessionPools.put(sid, session);
            addOnlineCount();
            System.out.println(sid + " 加入webSocket！当前人数为" + onlineNum);
            Player player = new Player();
            player.setId(sid);
            player.setName(user.getName());
            player.setHead(user.getHead());
            playPools.put(sid, player);
            sendMessage(session, getJsonStr("loginSuccess", "", ""));
            sendInfoAll(getJsonStr("playerList", "", playMap));
        } else {
            try {
                sendMessage(session, getJsonStr("error", "xitong", "你是个假用户"));
                session.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public void sendGameInfo() {
        JSONObject gameInfo = new JSONObject();
        gameInfo.put("playerList",playMap);
        sendInfoAll(getJsonStr("gameInfo", "", gameInfo));

    }

    //关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "sid") String sid) {
        sessionPools.remove(sid);
        playPools.remove(sid);
        subOnlineCount();
        System.out.println(sid + " 断开webSocket连接！当前人数为" + onlineNum);
        sendInfoAll(getJsonStr("onlineNum", "", playPools));
    }

    //收到客户端信息
    @OnMessage
    public void onMessage(String dataJson, Session session) throws IOException {
        System.out.println("收到数据：" + dataJson);
        try {
            JSONObject data = JSONObject.parseObject(dataJson);
            String type = data.getString("type");
            if ("join".equals(type)) {
                Integer position = data.getInteger("position");
                Integer sid = data.getInteger("sid");
                //判断是否有人
                Player player = playMap.get(position);
                if (player == null) {
                    player = playPools.get(sid);
                    playMap.put(position, player);
                    sendInfoAll(getJsonStr("playerList", "", playMap));
                } else {
                    sendMessage(session, getJsonStr("playerList", "", playMap));
                    sendMessage(session, getJsonStr("error", "xitong", "当前已经有人在这个位置了，请选择其他位置"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();

        }

    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable) {
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    public static void addOnlineCount() {
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

    public static String getJsonStr(String type, String sid, Object data) {
        JSONObject json = new JSONObject();
        json.put("type", type);
        json.put("sid", sid);
        json.put("data", data);
        return json.toString();
    }


}